home *** CD-ROM | disk | FTP | other *** search
/ Amiga Games Extra 1996 September / Amiga Games Extra CD-ROM 9-1996.iso / userbox / publicdomain / vim-4.2 / src / main.c < prev    next >
C/C++ Source or Header  |  1996-06-15  |  29KB  |  1,071 lines

  1. /* vi:set ts=4 sw=4:
  2.  *
  3.  * VIM - Vi IMproved        by Bram Moolenaar
  4.  *
  5.  * Do ":help uganda"  in Vim to read copying and usage conditions.
  6.  * Do ":help credits" in Vim to see a list of people who contributed.
  7.  */
  8.  
  9. #define EXTERN
  10. #include "vim.h"
  11. #include "globals.h"
  12. #include "proto.h"
  13. #include "option.h"
  14.  
  15. #ifdef SPAWNO
  16. # include <spawno.h>            /* special MSDOS swapping library */
  17. #endif
  18.  
  19. static void usage __PARMS((int, char_u *));
  20. static int stdout_notty = FALSE;            /* is stdout not a terminal? */
  21.  
  22. /*
  23.  * Types of usage message required.  These must match the array of error
  24.  * messages in usage().
  25.  */
  26. #define USAGE_UNKNOWN_OPTION    0
  27. #define USAGE_TOO_MANY_ARGS        1
  28. #define USAGE_ARG_MISSING        2
  29. #define USAGE_GARBAGE            3
  30.  
  31.     static void
  32. usage(n, str)
  33.     int        n;
  34.     char_u    *str;
  35. {
  36.     register int i;
  37.     static char_u *(use[]) = {(char_u *)"[file ..]",
  38.                             (char_u *)"-t tag",
  39.                             (char_u *)"-e [errorfile]"};
  40.     static char_u *(errors[]) =  {(char_u *)"Unknown option",
  41.                                 (char_u *)"Too many arguments",
  42.                                 (char_u *)"Argument missing after",
  43.                                 (char_u *)"Garbage after option",
  44.                                 };
  45.  
  46. #if defined(UNIX) || defined(__EMX__)
  47.     reset_signals();        /* kill us with CTRL-C here, if you like */
  48. #endif
  49.  
  50.     fprintf(stderr, longVersion);
  51.     fprintf(stderr, "\n");
  52.     fprintf(stderr, (char *)errors[n]);
  53.     if (str != NULL)
  54.         fprintf(stderr, ": \"%s\"", str);
  55.     fprintf(stderr, "\nusage:");
  56.     for (i = 0; ; ++i)
  57.     {
  58.         fprintf(stderr, " vim [options] ");
  59.         fprintf(stderr, (char *)use[i]);
  60.         if (i == (sizeof(use) / sizeof(char_u *)) - 1)
  61.             break;
  62.         fprintf(stderr, "\n   or:");
  63.     }
  64.  
  65.     fprintf(stderr, "\n\nOptions:\n");
  66. #ifdef USE_GUI
  67.     fprintf(stderr, "   -g\t\t\tRun using GUI\n");
  68.     fprintf(stderr, "   -f\t\t\tForeground: Don't fork when starting GUI\n");
  69. #endif
  70.     fprintf(stderr, "   -R  or  -v\t\tReadonly mode (view mode)\n");
  71.     fprintf(stderr, "   -b\t\t\tBinary mode\n");
  72.     fprintf(stderr, "   -l\t\t\tLisp mode\n");
  73.     fprintf(stderr, "   -n\t\t\tNo swap file, use memory only\n");
  74.     fprintf(stderr, "   -r\t\t\tList swap files\n");
  75.     fprintf(stderr, "   -r (with file name)\tRecover crashed session\n");
  76.     fprintf(stderr, "   -L\t\t\tSame as -r\n");
  77. #ifdef AMIGA
  78.     fprintf(stderr, "   -x\t\t\tDon't use newcli to open window\n");
  79.     fprintf(stderr, "   -d <device>\t\tUse <device> for I/O\n");
  80. #endif
  81. #ifdef RIGHTLEFT
  82.     fprintf(stderr, "   -H\t\t\tstart in Hebrew mode\n");
  83. #endif
  84.     fprintf(stderr, "   -T <terminal>\tSet terminal type to <terminal>\n");
  85.     fprintf(stderr, "   -o[N]\t\tOpen N windows (default: one for each file)\n");
  86.     fprintf(stderr, "   +\t\t\tStart at end of file\n");
  87.     fprintf(stderr, "   +<lnum>\t\tStart at line <lnum>\n");
  88.     fprintf(stderr, "   -c <command>\t\tExecute <command> first\n");
  89.     fprintf(stderr, "   -s <scriptin>\tRead commands from script file <scriptin>\n");
  90.     fprintf(stderr, "   -w <scriptout>\tAppend commands to script file <scriptout>\n");
  91.     fprintf(stderr, "   -W <scriptout>\tWrite commands to script file <scriptout>\n");
  92.     fprintf(stderr, "   -u <vimrc>\t\tUse <vimrc> instead of any .vimrc\n");
  93.     fprintf(stderr, "   -i <viminfo>\t\tUse <viminfo> instead of .viminfo\n");
  94.     fprintf(stderr, "   --\t\t\tEnd of options\n");
  95.  
  96. #ifdef USE_GUI_X11
  97. # ifdef USE_GUI_MOTIF
  98.     fprintf(stderr, "\nOptions recognised by gvim (Motif version):\n");
  99. # else
  100. #  ifdef USE_GUI_ATHENA
  101.     fprintf(stderr, "\nOptions recognised by gvim (Athena version):\n");
  102. #  endif /* USE_GUI_ATHENA */
  103. # endif /* USE_GUI_MOTIF */
  104.     fprintf(stderr, "   -display <display>\tRun vim on <display>\n");
  105.     fprintf(stderr, "   -iconic\t\tStart vim iconified\n");
  106. # if 0
  107.     fprintf(stderr, "   -name <name>\t\tUse resource as if vim was <name>\n");
  108.     fprintf(stderr, "\t\t\t  (Unimplemented)\n");
  109. # endif
  110.     fprintf(stderr, "   -background <color>\tUse <color> for the background (also: -bg)\n");
  111.     fprintf(stderr, "   -foreground <color>\tUse <color> for normal text (also: -fg)\n");
  112.     fprintf(stderr, "   -bold <color>\tUse <color> for bold text\n");
  113.     fprintf(stderr, "   -italic <color>\tUse <color> for italic text\n");
  114.     fprintf(stderr, "   -underline <color>\tUse <color> for underlined text (also: -ul)\n");
  115.     fprintf(stderr, "   -cursor <color>\tUse <color> for cursor\n");
  116.     fprintf(stderr, "   -font <font>\t\tUse <font> for normal text (also: -fn)\n");
  117.     fprintf(stderr, "   -boldfont <font>\tUse <font> for bold text\n");
  118.     fprintf(stderr, "   -italicfont <font>\tUse <font> for italic text\n");
  119.     fprintf(stderr, "   -geometry <geom>\tUse <geom> for initial geometry (also: -geom)\n");
  120.     fprintf(stderr, "   -borderwidth <width>\tUse a border width of <width> (also: -bw)\n");
  121.     fprintf(stderr, "   -scrollbarwidth <width>\tUse a scrollbar width of <width> (also: -sw)\n");
  122.     fprintf(stderr, "   -menuheight <height>\tUse a menu bar height of <height> (also: -mh)\n");
  123.     fprintf(stderr, "   -reverse\t\tUse reverse video (also: -rv)\n");
  124.     fprintf(stderr, "   +reverse\t\tDon't use reverse video (also: +rv)\n");
  125.     fprintf(stderr, "   -xrm <resource>\tSet the specified resource\n");
  126. #endif /* USE_GUI_X11 */
  127.  
  128.     mch_windexit(1);
  129. }
  130.  
  131. #ifdef HAVE_LOCALE_H
  132. # include <locale.h>
  133. #endif
  134.  
  135.     void
  136. main(argc, argv)
  137.     int                argc;
  138.     char          **argv;
  139. {
  140.     char_u           *initstr;        /* init string from the environment */
  141.     char_u           *term = NULL;    /* specified terminal name */
  142.     char_u           *fname = NULL;    /* file name from command line */
  143.     char_u           *command = NULL;    /* command from + or -c option */
  144.     char_u           *tagname = NULL;    /* tag from -t option */
  145.     char_u           *use_vimrc = NULL;    /* vimrc from -u option */
  146.     int             c;
  147.     int                doqf = 0;
  148.     int                i;
  149.     int                bin_mode = FALSE;        /* -b option used */
  150.     int                window_count = 1;        /* number of windows to use */
  151.     int                arg_idx = 0;            /* index for arg_files[] */
  152.     int                check_version = FALSE;    /* check .vimrc version number */
  153.     int                argv_idx;                /* index in argv[n][] */
  154.  
  155. #if defined(MSDOS) || defined(WIN32) || defined(OS2)
  156.     static struct initmap
  157.     {
  158.         char_u        *arg;
  159.         int            mode;
  160.     } initmappings[] =
  161.     {
  162.         /* normal and visual mode */
  163. #ifdef MSDOS
  164.         {(char_u *)"\316w H", NORMAL+VISUAL},        /* CTRL-HOME is 'H' */
  165.         {(char_u *)"\316u L", NORMAL+VISUAL},        /* CTRL-END is 'L' */
  166.         {(char_u *)"\316\204 1G", NORMAL+VISUAL},    /* CTRL-PageUp is '1G' */
  167.         {(char_u *)"\316v G", NORMAL+VISUAL},        /* CTRL-PageDown is 'G' */
  168. #else /* WIN32 */
  169.         /* Use the Windows (CUA) keybindings */
  170.         {(char_u *)"\316w 1G", NORMAL+VISUAL},        /* CTRL-HOME is '1G' */
  171.         {(char_u *)"\316u G$", NORMAL+VISUAL},        /* CTRL-END is 'G$' */
  172.         {(char_u *)"\316\204 H", NORMAL+VISUAL},    /* CTRL-PageUp is 'H' */
  173.         {(char_u *)"\316v L$", NORMAL+VISUAL},        /* CTRL-PageDown is 'L$' */
  174.         {(char_u *)"\316s B", NORMAL+VISUAL},        /* CTRL-Left is 'B' */
  175.         {(char_u *)"\316t W", NORMAL+VISUAL},        /* CTRL-Right is 'W' */
  176. #endif /* WIN32 */
  177.  
  178.         /* insert mode */
  179. #ifdef MSDOS
  180.         {(char_u *)"\316w \017H", INSERT},            /* CTRL-HOME is '^OH' */
  181.         {(char_u *)"\316u \017L", INSERT},            /* CTRL-END is '^OL' */
  182.         {(char_u *)"\316\204 \017\061G", INSERT},    /* CTRL-PageUp is '^O1G' */
  183.         {(char_u *)"\316v \017G", INSERT},            /* CTRL-PageDown is '^OG' */
  184. #else /* WIN32 */
  185.         /* Use the Windows (CUA) keybindings */
  186.         {(char_u *)"\316w \017\061G", INSERT},        /* CTRL-HOME is '^O1G' */
  187.         {(char_u *)"\316u \017G\017$", INSERT},        /* CTRL-END is '^OG^O$' */
  188.         {(char_u *)"\316\204 \017H",INSERT},        /* CTRL-PageUp is '^OH'*/
  189.         {(char_u *)"\316v \017L\017$", INSERT},        /* CTRL-PageDown ='^OL^O$'*/
  190.         {(char_u *)"\316s \017B", INSERT},            /* CTRL-Left is '^OB' */
  191.         {(char_u *)"\316t \017W", INSERT},            /* CTRL-Right is '^OW' */
  192. #endif /* WIN32 */
  193.     };
  194. #endif
  195.  
  196. #ifdef __EMX__
  197.     _wildcard(&argc, &argv);
  198. #endif
  199.  
  200. #ifdef HAVE_LOCALE_H
  201.     setlocale(LC_ALL, "");        /* for ctype() and the like */
  202. #endif
  203.  
  204. #ifdef USE_GUI
  205.     gui_prepare(&argc, argv);    /* Prepare for possibly starting GUI sometime */
  206. #endif
  207.  
  208. /*
  209.  * Check if we have an interactive window.
  210.  * On the Amiga: If there is no window, we open one with a newcli command
  211.  * (needed for :! to * work). mch_check_win() will also handle the -d argument.
  212.  */
  213.     stdout_notty = (mch_check_win(argc, argv) == FAIL);
  214.  
  215. /*
  216.  * allocate the first window and buffer. Can't do anything without it
  217.  */
  218.     if ((curwin = win_alloc(NULL)) == NULL ||
  219.                         (curbuf = buflist_new(NULL, NULL, 1L, FALSE)) == NULL)
  220.         mch_windexit(0);
  221.     curwin->w_buffer = curbuf;
  222.     screen_start();                    /* don't know where cursor is yet */
  223.  
  224. /*
  225.  * Allocate space for the generic buffers (needed for set_init_1()).
  226.  */
  227.     if ((IObuff = alloc(IOSIZE)) == NULL ||
  228.                             (NameBuff = alloc(MAXPATHL)) == NULL)
  229.         mch_windexit(0);
  230.  
  231. /*
  232.  * Set the default values for the options.
  233.  * First find out the home directory, needed to expand "~" in options.
  234.  */
  235.     init_homedir();                /* find real value of $HOME */
  236.     set_init_1();
  237.  
  238. /*
  239.  * If the executable is called "view" we start in readonly mode.
  240.  */
  241.     if (STRCMP(gettail((char_u *)argv[0]), (char_u *)"view") == 0)
  242.     {
  243.         readonlymode = TRUE;
  244.         curbuf->b_p_ro = TRUE;
  245.         if (p_uc)                    /* if we are doing any updating.. */
  246.             p_uc = 10000;            /* ..don't update very often */
  247.     }
  248.  
  249. /*
  250.  * If the executable is called "gvim" we run the GUI version.
  251.  */
  252.     if (STRCMP(gettail((char_u *)argv[0]), (char_u *)"gvim") == 0)
  253.     {
  254. #ifdef USE_GUI
  255.         gui.starting = TRUE;
  256. #else
  257.         fprintf(stderr, (char *)e_nogvim);
  258.         mch_windexit(2);
  259. #endif
  260.     }
  261.  
  262.     ++argv;
  263.     /*
  264.      * Process the command line arguments
  265.      *        '+{command}'    execute command
  266.      *        '-b'            binary
  267.      *        '-c {command}'    execute command
  268.      *        '-d {device}'    device (for Amiga)
  269.      *        '-f'            Don't fork when starging GUI. (if USE_GUI defined)
  270.       *        '-g'            Run with GUI. (if USE_GUI defined)
  271.      *        '-H'            Start in right-left mode
  272.      *        '-i viminfo'    use instead of p_viminfo
  273.      *        '-n'            no .vim file
  274.      *        '-o[N]'            open N windows (default: number of files)
  275.      *        '-r'            recovery mode
  276.      *        '-L'            recovery mode
  277.      *         '-s scriptin'    read from script file
  278.      *        '-T terminal'    terminal name
  279.      *        '-u vimrc'        read initializations from a file
  280.      *        '-v'             view or Readonly mode
  281.      *        '-R'            view or Readonly mode
  282.      *        '-w scriptout'    write to script file (append)
  283.      *        '-W scriptout'    write to script file (overwrite)
  284.      *        '-x'            open window directly, not with newcli
  285.      */
  286.     argv_idx = 1;            /* active option letter is argv[0][argv_idx] */
  287.  
  288.     while (argc > 1 && ((c = argv[0][0]) == '+' || (c == '-' &&
  289.                                    vim_strchr((char_u *)"bcdfgHilLnorRsTuvwWx",
  290.                                              c = argv[0][argv_idx]) != NULL)))
  291.     {
  292.         ++argv_idx;            /* advance to next option letter by default */
  293.         switch (c)
  294.         {
  295.         case '+':             /* + or +{number} or +/{pat} or +{command} */
  296.             argv_idx = -1;            /* skip to next argument */
  297.             if (argv[0][1] == NUL)
  298.                 command = (char_u *)"$";
  299.             else
  300.                 command = (char_u *)&(argv[0][1]);
  301.             break;
  302.  
  303.         case 'b':
  304.             bin_mode = TRUE;        /* postpone to after reading .exrc files */
  305.             break;
  306.  
  307. #ifdef USE_GUI
  308.         case 'f':
  309.             gui.dofork = FALSE;        /* don't fork() when starting GUI */
  310.             break;
  311. #endif
  312.  
  313.         case 'g':
  314. #ifdef USE_GUI
  315.             gui.starting = TRUE;    /* start GUI a bit later */
  316. #else
  317.             fprintf(stderr, (char *)e_nogvim);
  318.             mch_windexit(2);
  319. #endif
  320.             break;
  321.  
  322.         case 'H':                /* start in Hebrew mode: rl + hkmap set */
  323. #ifdef RIGHTLEFT
  324.             curwin->w_p_rl = p_hkmap = TRUE;
  325. #else
  326.             fprintf(stderr, (char *)e_nohebrew);
  327.             mch_windexit(2);
  328. #endif
  329.             break;
  330.  
  331.         case 'l':            /* -l: lisp mode, 'lisp' and 'showmatch' on */
  332.             curbuf->b_p_lisp = TRUE;
  333.             p_sm = TRUE;
  334.             break;
  335.  
  336.         case 'n':
  337.             p_uc = 0;
  338.             break;
  339.  
  340.         case 'o':
  341.             window_count = 0;        /* default: open window for each file */
  342.             if (isdigit(argv[0][argv_idx]))
  343.             {
  344.                 window_count = atoi(&(argv[0][argv_idx]));
  345.                 while (isdigit(argv[0][argv_idx]))
  346.                     ++argv_idx;
  347.             }
  348.             break;
  349.  
  350.         case 'r':
  351.         case 'L':
  352.             recoverymode = 1;
  353.             break;
  354.         
  355.         case 'v':
  356.         case 'R':
  357.             readonlymode = TRUE;
  358.             curbuf->b_p_ro = TRUE;
  359.             if (p_uc)                    /* if we are doing any updating.. */
  360.                 p_uc = 10000;            /* ..don't update very often */
  361.             break;
  362.  
  363.         case 'x':
  364.             break;    /* This is ignored as it is handled in mch_check_win() */
  365.  
  366.  
  367.         case 'w':
  368.             if (isdigit(argv[0][argv_idx]))    /* -w{number}; set window height */
  369.             {
  370.                 argv_idx = -1;
  371.                 break;                        /* not implemented, ignored */
  372.             }
  373.             /* FALLTHROUGH */
  374.  
  375.         default:    /* options with argument */
  376.             /*
  377.              * Check there's no garbage immediately after the option letter.
  378.              */
  379.             if (argv[0][argv_idx] != NUL)
  380.                 usage(USAGE_GARBAGE, (char_u *)argv[0]);
  381.  
  382.             --argc;
  383.             if (argc < 2)
  384.                 usage(USAGE_ARG_MISSING, (char_u *)argv[0]);
  385.             ++argv;
  386.             argv_idx = -1;
  387.  
  388.             switch (c)
  389.             {
  390.             case 'c':            /* -c {command} */
  391.                 command = (char_u *)argv[0];
  392.                 break;
  393.  
  394.         /*    case 'd':    This is ignored as it is handled in mch_check_win() */
  395.  
  396.             case 'i':            /* -i {viminfo} */
  397.                 use_viminfo = (char_u *)argv[0];
  398.                 break;
  399.             
  400.             case 's':            /* -s {scriptin} */
  401.                 if (scriptin[0] != NULL)
  402.                 {
  403.                     fprintf(stderr,
  404.                             "Attempt to open script file again: \"%s %s\"\n",
  405.                             argv[-1], argv[0]);
  406.                     mch_windexit(2);
  407.                 }
  408.                 if ((scriptin[0] = fopen(argv[0], READBIN)) == NULL)
  409.                 {
  410.                     fprintf(stderr, "Cannot open \"%s\" for reading\n", argv[0]);
  411.                     mch_windexit(2);
  412.                 }
  413.                 break;
  414.             
  415. /*
  416.  * The -T term option is always available and when HAVE_TERMLIB is supported
  417.  * it overrides the environment variable TERM.
  418.  */
  419.             case 'T':            /* -T {terminal} */
  420.                 term = (char_u *)argv[0];
  421.                 break;
  422.             
  423.             case 'u':            /* -u {vimrc} */
  424.                 use_vimrc = (char_u *)argv[0];
  425.                 break;
  426.             
  427.             case 'w':            /* -w {scriptout} (append) */
  428.             case 'W':            /* -W {scriptout} (overwrite) */
  429.                 if (scriptout != NULL)
  430.                 {
  431.                     fprintf(stderr,
  432.                             "Attempt to open script file again: \"%s %s\"\n",
  433.                             argv[-1], argv[0]);
  434.                     mch_windexit(2);
  435.                 }
  436.                 if ((scriptout = fopen(argv[0],
  437.                                     c == 'w' ? APPENDBIN : WRITEBIN)) == NULL)
  438.                 {
  439.                     fprintf(stderr, "cannot open \"%s\" for output\n", argv[0]);
  440.                     mch_windexit(2);
  441.                 }
  442.                 break;
  443.             }
  444.         }
  445.         /*
  446.          * If there are no more letters after the current "-", go to next
  447.          * argument.  argv_idx is set to -1 when the current argument is to be
  448.          * skipped.
  449.          */
  450.         if (argv_idx <= 0 || argv[0][argv_idx] == NUL)
  451.         {
  452.             --argc;
  453.             ++argv;
  454.             argv_idx = 1;
  455.         }
  456.     }
  457.  
  458.     /* note that we may use mch_windexit() before mch_windinit()! */
  459.     mch_windinit();                /* inits Rows and Columns */
  460. /*
  461.  * Set the default values for the options that use Rows and Columns.
  462.  */
  463.     set_init_2();
  464.  
  465.     firstwin->w_height = Rows - 1;
  466.     cmdline_row = Rows - 1;
  467.  
  468.     /*
  469.      * Process the other command line arguments.
  470.      * -e[errorfile]    quickfix mode
  471.      * -t[tagname]        jump to tag
  472.      * [--] [file ..]    file names
  473.      */
  474.     if (argc > 1)
  475.     {
  476.         if (argv[0][0] == '-' && (argv[0][1] != '-' || argv[0][2] != NUL))
  477.         {
  478.             switch (argv[0][1])
  479.             {
  480.               case 'e':            /* -e QuickFix mode */
  481.                 switch (argc)
  482.                 {
  483.                     case 2:
  484.                             if (argv[0][2])    /* -eerrorfile */
  485.                                 p_ef = (char_u *)argv[0] + 2;
  486.                             break;                /* -e */
  487.  
  488.                     case 3:                    /* -e errorfile */
  489.                             if (argv[0][2] != NUL)
  490.                                 usage(USAGE_GARBAGE, (char_u *)argv[0]);
  491.                             ++argv;
  492.                             p_ef = (char_u *)argv[0];
  493.                             break;
  494.  
  495.                     default:                /* argc > 3: too many arguments */
  496.                             usage(USAGE_TOO_MANY_ARGS, NULL);
  497.                 }
  498.                 doqf = 1;
  499.                 break;
  500.  
  501.             case 't':            /* -t tag  or -ttag */
  502.                 switch (argc)
  503.                 {
  504.                     case 2:
  505.                             if (argv[0][2])        /* -ttag */
  506.                             {
  507.                                 tagname = (char_u *)argv[0] + 2;
  508.                                 break;
  509.                             }
  510.                             usage(USAGE_ARG_MISSING, (char_u *)argv[0]);
  511.                             break;
  512.  
  513.                     case 3:                        /* -t tag */
  514.                             if (argv[0][2] != NUL)    /* also -ttag?! */
  515.                                 usage(USAGE_GARBAGE, (char_u *)argv[0]);
  516.                             ++argv;
  517.                             tagname = (char_u *)argv[0];
  518.                             break;
  519.  
  520.                     default:                /* argc > 3: too many arguments */
  521.                             usage(USAGE_TOO_MANY_ARGS, NULL);
  522.                 }
  523.                 break;
  524.  
  525.             default:
  526.                 usage(USAGE_UNKNOWN_OPTION, (char_u *)argv[0]);
  527.             }
  528.         }
  529.         else                /* must be a file name */
  530.         {
  531.             /*
  532.              * Skip a single "--" argument, used in front of a file name that
  533.              * starts with '-'.
  534.              */
  535.             if (argc > 2 && STRCMP(argv[0], "--") == 0)
  536.             {
  537.                 ++argv;
  538.                 --argc;
  539.             }
  540.  
  541. #if (!defined(UNIX) && !defined(__EMX__)) || defined(ARCHIE)
  542.             if (ExpandWildCards(argc - 1, (char_u **)argv, &arg_count,
  543.                     &arg_files, TRUE, TRUE) == OK && arg_count != 0)
  544.             {
  545.                 fname = arg_files[0];
  546.                 arg_exp = TRUE;
  547.             }
  548. #else
  549.             arg_files = (char_u **)argv;
  550.             arg_count = argc - 1;
  551.             fname = (char_u *)argv[0];
  552. #endif
  553.             if (arg_count > 1)
  554.             {
  555.                 printf("%d files to edit\n", arg_count);
  556.                 screen_start();            /* don't know where cursor is now */
  557.             }
  558.         }
  559.     }
  560.  
  561.     RedrawingDisabled = TRUE;
  562.  
  563.     /*
  564.      * When listing swap file names, don't do cursor positioning et. al.
  565.      */
  566.     if (recoverymode && fname == NULL)
  567.         full_screen = FALSE;
  568.  
  569. #ifdef USE_GUI
  570.     /*
  571.      * We don't want to open the GUI window until after we've read .vimrc,
  572.      * otherwise we don't know what font we will use, and hence we don't know
  573.      * what size the window should be.  So if there are errors in the .vimrc
  574.      * file, they will have to go to the terminal -- webb
  575.      */
  576.     if (gui.starting)
  577.         full_screen = FALSE;
  578. #endif
  579.  
  580.     /*
  581.      * Now print a warning if stdout is not a terminal.
  582.      */
  583.     if (full_screen && (stdout_notty || mch_check_input() == FAIL))
  584.     {
  585.         if (stdout_notty)
  586.             fprintf(stderr, "Vim: Warning: Output is not to a terminal\n");
  587.         if (mch_check_input() == FAIL)
  588.             fprintf(stderr, "Vim: Warning: Input is not from a terminal\n");
  589.         mch_delay(2000L, TRUE);
  590.         screen_start();            /* don't know where cursor is now */
  591.     }
  592.  
  593.     curbuf->b_nwindows = 1;        /* there is one window */
  594.     win_init(curwin);            /* init current window */
  595.     init_yank();                /* init yank buffers */
  596.     if (full_screen)
  597.         termcapinit(term);        /* set terminal name and get terminal
  598.                                    capabilities */
  599.     screenclear();                /* clear screen (just inits screen structures,
  600.                                     because starting is TRUE) */
  601.  
  602.     if (full_screen)
  603.         msg_start();        /* in case a mapping or error message is printed */
  604.     msg_scroll = TRUE;
  605.     no_wait_return = TRUE;
  606.  
  607. #if defined(MSDOS) || defined(WIN32) || defined(OS2)
  608. /*
  609.  * Default mapping for some often used keys.
  610.  * Need to put string in allocated memory, because do_map() will modify it.
  611.  */
  612.     for (i = 0; i < sizeof(initmappings) / sizeof(struct initmap); ++i)
  613.     {
  614.         initstr = strsave(initmappings[i].arg);
  615.         if (initstr != NULL)
  616.         {
  617.             do_map(0, initstr, initmappings[i].mode);
  618.             vim_free(initstr);
  619.         }
  620.     }
  621. #endif
  622.  
  623. /*
  624.  * If -u option give, use only the initializations from that file and nothing
  625.  * else.
  626.  */
  627.     if (use_vimrc != NULL)
  628.     {
  629.         if (STRCMP(use_vimrc, "NONE") != 0)
  630.         {
  631.             if (do_source(use_vimrc, FALSE) == OK)
  632.                 check_version = TRUE;
  633.             else
  634.                 EMSG2("Cannot read from \"%s\"", use_vimrc);
  635.         }
  636.     }
  637.     else
  638.     {
  639.  
  640.     /*
  641.      * get system wide defaults (for unix)
  642.      */
  643. #if defined(HAVE_CONFIG_H) || defined(OS2)
  644.         if (do_source(sys_vimrc_fname, TRUE) == OK)
  645.             check_version = TRUE;
  646. #endif
  647.  
  648.     /*
  649.      * Try to read initialization commands from the following places:
  650.      * - environment variable VIMINIT
  651.      * - user vimrc file (s:.vimrc for Amiga, ~/.vimrc for Unix)
  652.      * - environment variable EXINIT
  653.      * - user exrc file (s:.exrc for Amiga, ~/.exrc for Unix)
  654.      * The first that exists is used, the rest is ignored.
  655.      */
  656.         if ((initstr = vim_getenv((char_u *)"VIMINIT")) != NULL &&
  657.                                                         *initstr != NUL)
  658.         {
  659.             sourcing_name = (char_u *)"VIMINIT";
  660.             do_cmdline(initstr, TRUE, TRUE);
  661.             sourcing_name = NULL;
  662.         }
  663.         else if (do_source((char_u *)USR_VIMRC_FILE, TRUE) == FAIL)
  664.         {
  665.             if ((initstr = vim_getenv((char_u *)"EXINIT")) != NULL)
  666.             {
  667.                 sourcing_name = (char_u *)"EXINIT";
  668.                 do_cmdline(initstr, TRUE, TRUE);
  669.                 sourcing_name = NULL;
  670.             }
  671.             else
  672.                 (void)do_source((char_u *)USR_EXRC_FILE, FALSE);
  673.         }
  674.         else
  675.             check_version = TRUE;
  676.  
  677.     /*
  678.      * Read initialization commands from ".vimrc" or ".exrc" in current
  679.      * directory.  This is only done if the 'exrc' option is set.
  680.      * Because of security reasons we disallow shell and write commands now,
  681.      * except for unix if the file is owned by the user or 'secure' option has
  682.      * been reset in environmet of global ".exrc" or ".vimrc".
  683.      * Only do this if VIMRC_FILE is not the same as USR_VIMRC_FILE or
  684.      * sys_vimrc_fname.
  685.      */
  686.         if (p_exrc)
  687.         {
  688. #ifdef UNIX
  689.             {
  690.                 struct stat s;
  691.  
  692.                 /* if ".vimrc" file is not owned by user, set 'secure' mode */
  693.                 if (stat(VIMRC_FILE, &s) || s.st_uid != getuid())
  694.                     secure = p_secure;
  695.             }
  696. #else
  697.             secure = p_secure;
  698. #endif
  699.  
  700.             i = FAIL;
  701.             if (fullpathcmp((char_u *)USR_VIMRC_FILE,
  702.                                              (char_u *)VIMRC_FILE) != FPC_SAME
  703. #if defined(HAVE_CONFIG_H) || defined(OS2)
  704.                     && fullpathcmp(sys_vimrc_fname,
  705.                                              (char_u *)VIMRC_FILE) != FPC_SAME
  706. #endif
  707.                     )
  708.                 i = do_source((char_u *)VIMRC_FILE, TRUE);
  709. #ifdef UNIX
  710.             if (i == FAIL)
  711.             {
  712.                 struct stat s;
  713.  
  714.                     /* if ".exrc" is not owned by user set 'secure' mode */
  715.                 if (stat(EXRC_FILE, &s) || s.st_uid != getuid())
  716.                     secure = p_secure;
  717.                 else
  718.                     secure = 0;
  719.             }
  720.             else
  721.                 check_version = TRUE;
  722. #endif
  723.             if (i == FAIL && fullpathcmp((char_u *)USR_EXRC_FILE,
  724.                                              (char_u *)EXRC_FILE) != FPC_SAME)
  725.                 (void)do_source((char_u *)EXRC_FILE, FALSE);
  726.         }
  727.     }
  728.  
  729.     /*
  730.      * Recovery mode without a file name: List swap files.
  731.      * This uses the 'dir' option, therefore it must be after the
  732.      * initializations.
  733.      */
  734.     if (recoverymode && fname == NULL)
  735.     {
  736.         recover_names(NULL, TRUE, 0);
  737.         mch_windexit(0);
  738.     }
  739.  
  740.     /*
  741.      * Set a few option defaults after reading .vimrc files:
  742.      * 'title' and 'icon', Unix: 'shellpipe' and 'shellredir'.
  743.      */
  744.     set_init_3();
  745.  
  746. #ifdef USE_GUI
  747.     if (gui.starting)
  748.     {
  749.         gui_start();
  750.         gui.starting = FALSE;
  751.         full_screen = TRUE;
  752.     }
  753. #endif
  754.  
  755.     /*
  756.      * If we read a .vimrc but it does not contain a "version 4.0" command,
  757.      * give the user a pointer to the help for the new version.
  758.      */
  759.     if (check_version && found_version == 0)
  760.     {
  761.         MSG("This is Vim version 4.0.");
  762.         MSG("No \":version 4.0\" command found in any .vimrc.");
  763.         MSG("Use \":help version\" for info about this new version.");
  764.     }
  765.  
  766. #ifdef VIMINFO
  767. /*
  768.  * Read in registers, history etc, but not marks, from the viminfo file
  769.  */
  770.     if (*p_viminfo != NUL)
  771.         read_viminfo(NULL, TRUE, FALSE, FALSE);
  772. #endif /* VIMINFO */
  773.  
  774. #ifdef SPAWNO            /* special MSDOS swapping library */
  775.     init_SPAWNO("", SWAP_ANY);
  776. #endif
  777.  
  778.     if (bin_mode)                    /* -b option used */
  779.     {
  780.         set_options_bin(curbuf->b_p_bin, 1);
  781.         curbuf->b_p_bin = 1;        /* binary file I/O */
  782.     }
  783.  
  784.     /* Don't set the file name if there was a command in .vimrc that already
  785.      * loaded the file */
  786.     if (curbuf->b_filename == NULL)
  787.     {
  788.         (void)setfname(fname, NULL, TRUE);    /* includes maketitle() */
  789.         ++arg_idx;                            /* used first argument name */
  790.     }
  791.  
  792.     if (window_count == 0)
  793.         window_count = arg_count;
  794.     if (window_count > 1)
  795.     {
  796.         /* Don't change the windows if there was a command in .vimrc that
  797.          * already split some windows */
  798.         if (firstwin->w_next == NULL)
  799.             window_count = make_windows(window_count);
  800.         else
  801.             window_count = win_count();
  802.     }
  803.     else
  804.         window_count = 1;
  805.  
  806. /*
  807.  * "-e errorfile": Load the error file now.
  808.  * If the error file can't be read, exit before doing anything else.
  809.  */
  810.     if (doqf && qf_init() == FAIL)        /* if reading error file fails: exit */
  811.         mch_windexit(3);
  812.  
  813. /*
  814.  * Start putting things on the screen.
  815.  * Scroll screen down before drawing over it
  816.  * Clear screen now, so file message will not be cleared.
  817.  */
  818.     starting = FALSE;
  819.     no_wait_return = FALSE;
  820.     msg_scroll = FALSE;
  821. #ifdef USE_GUI
  822.     /*
  823.      * This seems to be required to make callbacks to be called now, instead
  824.      * of after things have been put on the screen, which then may be deleted
  825.      * when getting a resize callback.
  826.      */
  827.     if (gui.in_use)
  828.         gui_mch_wait_for_chars(50);
  829. #endif
  830.  
  831. /*
  832.  * When done something that is not allowed or error message call wait_return.
  833.  * This must be done before starttermcap(), because it may switch to another
  834.  * screen. It must be done after settmode(1), because we want to react on a
  835.  * single key stroke.
  836.  * Call settmode and starttermcap here, so the T_KS and T_TI may be defined
  837.  * by termcapinit and redifined in .exrc.
  838.  */
  839.     settmode(1);
  840.     if (secure == 2 || need_wait_return || msg_didany)
  841.         wait_return(TRUE);
  842.  
  843.     starttermcap();            /* start termcap if not done by wait_return() */
  844. #ifdef USE_MOUSE
  845.     setmouse();                            /* may start using the mouse */
  846. #endif
  847.     if (scroll_region)
  848.         scroll_region_reset();            /* In case Rows changed */
  849.  
  850.     secure = 0;
  851.  
  852.     scroll_start();
  853.     screenclear();                        /* clear screen */
  854.  
  855.     no_wait_return = TRUE;
  856.  
  857.     if (recoverymode)                    /* do recover */
  858.     {
  859.         msg_scroll = TRUE;                /* scroll message up */
  860.         ml_recover();
  861.         msg_scroll = FALSE;
  862.         if (curbuf->b_ml.ml_mfp == NULL) /* failed */
  863.             getout(1);
  864. #ifdef AUTOCMD
  865.         apply_autocmds(EVENT_BUFENTER, NULL, NULL);
  866. #endif
  867.         do_modelines();                    /* do modelines */
  868.     }
  869.     /* Only read the file if there is none for the current buffer, a command
  870.      * in the .vimrc might have loaded a file */
  871.     else if (curbuf->b_ml.ml_mfp == NULL)
  872.         (void)open_buffer();            /* create memfile and read file */
  873.  
  874.     setpcmark();
  875.  
  876.     /*
  877.      * When started with "-e errorfile" jump to first error now.
  878.      */
  879.     if (doqf)
  880.         qf_jump(0, 0);
  881.  
  882.     /*
  883.      * If opened more than one window, start editing files in the other windows.
  884.      * Make_windows() has already opened the windows.
  885.      */
  886.     for (i = 1; i < window_count; ++i)
  887.     {
  888.         if (curwin->w_next == NULL)            /* just checking */
  889.             break;
  890.         win_enter(curwin->w_next, FALSE);
  891.  
  892.         /* Only open the file if there is no file in this window yet (that can
  893.          * happen when .vimrc contains ":sall") */
  894.         if (curbuf == firstwin->w_buffer || curbuf->b_filename == NULL)
  895.         {
  896.             curwin->w_arg_idx = arg_idx;
  897.             /* edit file from arg list, if there is one */
  898.             (void)do_ecmd(0, arg_idx < arg_count ? arg_files[arg_idx] : NULL,
  899.                                         NULL, NULL, TRUE, (linenr_t)1, FALSE);
  900.             if (arg_idx == arg_count - 1)
  901.                 arg_had_last = TRUE;
  902.             ++arg_idx;
  903.         }
  904.         mch_breakcheck();
  905.         if (got_int)
  906.         {
  907.             (void)vgetc();        /* only break the file loading, not the rest */
  908.             break;
  909.         }
  910.     }
  911.     win_enter(firstwin, FALSE);                /* back to first window */
  912.     if (window_count > 1)
  913.         win_equal(curwin, FALSE);            /* adjust heights */
  914.  
  915.     /*
  916.      * If there are more file names in the argument list than windows,
  917.      * put the rest of the names in the buffer list.
  918.      */
  919.     while (arg_idx < arg_count)
  920.         (void)buflist_add(arg_files[arg_idx++]);
  921.  
  922.     /*
  923.      * Need to jump to the tag before executing the '-c command'.
  924.      * Makes "vim -c '/return' -t main" work.
  925.      */
  926.     if (tagname)
  927.     {
  928.         STRCPY(IObuff, "ta ");
  929.         STRCAT(IObuff, tagname);
  930.         do_cmdline(IObuff, TRUE, TRUE);
  931.     }
  932.  
  933.     if (command)
  934.     {
  935.         /*
  936.          * We start commands on line 0, make "vim +/pat file" match a
  937.          * pattern on line 1.
  938.          */
  939.         curwin->w_cursor.lnum = 0;
  940.         sourcing_name = (char_u *)"command line";
  941.         do_cmdline(command, TRUE, TRUE);
  942.         sourcing_name = NULL;
  943.     }
  944.  
  945.     RedrawingDisabled = FALSE;
  946.     redraw_later(NOT_VALID);
  947.     no_wait_return = FALSE;
  948.  
  949.     /* start in insert mode */
  950.     if (p_im)
  951.         need_start_insertmode = TRUE;
  952.  
  953. /*
  954.  * main command loop
  955.  */
  956.     for (;;)
  957.     {
  958.         if (stuff_empty())
  959.         {
  960.             if (need_check_timestamps)
  961.                 check_timestamps();
  962.             if (need_wait_return)        /* if wait_return still needed ... */
  963.                 wait_return(FALSE);        /* ... call it now */
  964.             if (need_start_insertmode)
  965.             {
  966.                 need_start_insertmode = FALSE;
  967.                 stuffReadbuff((char_u *)"i");    /* start insert mode next */
  968.                 /* skip the fileinfo message now, because it would be shown
  969.                  * after insert mode finishes! */
  970.                 need_fileinfo = FALSE;
  971.             }
  972.         }
  973.         dont_wait_return = FALSE;
  974.         if (got_int)
  975.         {
  976.             (void)vgetc();                /* flush all buffers */
  977.             got_int = FALSE;
  978.         }
  979.         adjust_cursor();                /* put cursor on an existing line */
  980.         msg_scroll = FALSE;
  981.         quit_more = FALSE;
  982.         keep_help_flag = FALSE;
  983.         /*
  984.          * If skip redraw is set (for ":" in wait_return()), don't redraw now.
  985.          * If there is nothing in the stuff_buffer or do_redraw is TRUE,
  986.          * update cursor and redraw.
  987.          */
  988.         if (skip_redraw)            
  989.             skip_redraw = FALSE;
  990.         else if (do_redraw || stuff_empty())
  991.         {
  992.             cursupdate();                /* Figure out where the cursor is based
  993.                                             on curwin->w_cursor. */
  994. #ifdef SLEEP_IN_EMSG
  995.             if (need_sleep)                /* sleep before redrawing */
  996.             {
  997.                 mch_delay(1000L, TRUE);
  998.                 need_sleep = FALSE;
  999.             }
  1000. #endif
  1001.             if (VIsual_active)
  1002.                 update_curbuf(INVERTED);/* update inverted part */
  1003.             if (must_redraw)
  1004.                 updateScreen(must_redraw);
  1005.             else if (redraw_cmdline)
  1006.                 showmode();
  1007.             if (keep_msg != NULL)
  1008.             {
  1009.                 if (keep_msg_highlight)
  1010.                 {
  1011.                     (void)set_highlight(keep_msg_highlight);
  1012.                     msg_highlight = TRUE;
  1013.                 }
  1014.                 msg(keep_msg);            /* display message after redraw */
  1015.             }
  1016.             if (need_fileinfo)            /* used after jumping to a tag */
  1017.             {
  1018.                 fileinfo(did_cd, TRUE, FALSE);
  1019.                 need_fileinfo = FALSE;
  1020.             }
  1021.  
  1022.             emsg_on_display = FALSE;    /* can delete error message now */
  1023.             msg_didany = FALSE;            /* reset lines_left in msg_start() */
  1024.             do_redraw = FALSE;
  1025.             showruler(FALSE);
  1026.  
  1027.             setcursor();
  1028.             cursor_on();
  1029.         }
  1030.  
  1031.         /*
  1032.          * get and execute a normal mode command
  1033.          */
  1034.         normal();
  1035.     }
  1036.     /*NOTREACHED*/
  1037. }
  1038.  
  1039.     void
  1040. getout(r)
  1041.     int             r;
  1042. {
  1043.     exiting = TRUE;
  1044.  
  1045.     /* Position the cursor on the last screen line, below all the text */
  1046. #ifdef USE_GUI
  1047.     if (!gui.in_use)
  1048. #endif
  1049.         windgoto((int)Rows - 1, 0);
  1050.  
  1051. #ifdef AUTOCMD
  1052.     apply_autocmds(EVENT_VIMLEAVE, NULL, NULL);
  1053.  
  1054.     /* Position the cursor again, the autocommands may have moved it */
  1055. # ifdef USE_GUI
  1056.     if (!gui.in_use)
  1057. # endif
  1058.         windgoto((int)Rows - 1, 0);
  1059. #endif
  1060.  
  1061. #ifdef VIMINFO
  1062.     /* Write out the registers, history, marks etc, to the viminfo file */
  1063.     if (*p_viminfo != NUL)
  1064.         write_viminfo(NULL, FALSE);
  1065. #endif /* VIMINFO */
  1066.  
  1067.     outchar('\r');
  1068.     outchar('\n');
  1069.     mch_windexit(r);
  1070. }
  1071.